package org.dbstar.scheduler.job;

import org.dbstar.scheduler.beans.Job;
import org.dbstar.scheduler.beans.JobResult;
import org.dbstar.scheduler.control.JobController;
import org.dbstar.scheduler.control.exception.DaoException;


/**
 * job执行器抽象基类
 * 
 * @author 代波
 * @since 1.0.0
 * @version 1.0.0
 * @date 2012-3-21
 */
public abstract class AbstractJobRunner implements JobRunner {
	protected final JobController jobController;
	private final Job job;

	public AbstractJobRunner(JobController jobController, Job job) {
		super();
		this.jobController = jobController;
		this.job = job;
	}

	@Override
	public final Job call() throws Exception {
		jobController.changeJobStatus(job.getIdentifier(), JobStatus.queue);
		JobResult jobResult = job.getResult();
		jobResult.init(job, jobController);
		//在重复执行的时候不再更新启动时间
		if (job.getLaunchTime() == null) {
			job.setLaunchTime(System.currentTimeMillis());
		}
		job.setFinishTime(null);
		changeJobStatus(JobStatus.run);
		try {
			boolean ok = run(job);
			job.setFinishTime(System.currentTimeMillis());
			changeJobStatus(ok ? JobStatus.finish : JobStatus.kill);
		} catch (Throwable e) {
			jobResult.setErrorException(e.getClass().getName() + ": " + e.getLocalizedMessage());
			job.setFinishTime(System.currentTimeMillis());
			changeJobStatus(JobStatus.error);
		}
		return job;
	}

	protected final void changeJobStatus(JobStatus newStatus) throws DaoException {
		updateJob();
		jobController.changeJobStatus(job.getIdentifier(), newStatus);
	}

	protected final void updateJob() throws DaoException {
		jobController.updateJob(job);
	}

	@Override
	public final Job getJob() {
		return job;
	}

	protected abstract boolean run(Job job) throws Exception;
}
